#include <string.h>
#include <stdio.h>
#include <iostream>
#define MAX 1000
#define SIZE 1000
using namespace std;

//学生结构体
struct person
{
    char p_name[10]; //姓名
    int p_num1;      //学号
    int p_num2;      //房号
};
struct book //辅助结构体
{
    struct person p[MAX];
    int num;
};
//排序函数
int paixv(struct book *abs)
{
    //对数字排序
    int i, j;
    struct person temp;
    for (j = 0; j < abs->num - 1; j++)
    {
        for (i = 0; i < abs->num - 1 - j; i++)
            if (abs->p[i].p_num1 > abs->p[i + 1].p_num1)
            {
                temp = abs->p[i];
                abs->p[i] = abs->p[i + 1];
                abs->p[i + 1] = temp;
            }
    }
    return 0;
}
//判断函数，判断该学生是否存在，可能重复的返回1，不会重复的返回地址，不存在返回-1
int fz1[1000]; //辅助数组，解决多人同名
int exist1(struct book *abs, string name)
{
    int i;
    for (i = 0; i < 1000; i++)
        fz1[i] = -1;
    int j = 0;
    for (i = 0; i < abs->num; i++)
    {
        if (abs->p[i].p_name == name) //判断是否存在
        {
            fz1[j] = i;
            j++;
        }
    }
    if (j != 0)
        return 1;
    else
        return -1; //不存在的情况
}
int exist2(struct book *abs, int num1)
{
    for (int i = 0; i < abs->num; i++)
    {
        if (abs->p[i].p_num1 == num1)
        {
            return i;
        }
    }
    return -1;
} //判断学号
int fz[1000]; //辅助数组，解决多人同房号
int exist3(struct book *abs, int num2)
{
    int i;
    for (i = 0; i < 1000; i++)
        fz[i] = -1;
    int j = 0;
    for (i = 0; i < abs->num; i++)
    {
        if (abs->p[i].p_num2 == num2) //判断是否存在
        {
            fz[j] = i;
            j++;
        }
    }
    if (j != 0)
        return 1;
    else
        return -1; //不存在的情况
} //判断房号
//加载文件内容
void loan_file(struct book *abs)
{
    struct person tmp; //临时结构体
    FILE *fp;          //文件指针

    if ((fp = fopen("readme.txt", "r+")) == NULL) //打开输入文件
    {
        fp = fopen("readme.txt", "w+");
        return;
    } //用只读文本打开文件

    while (fread(&tmp, sizeof(struct person), 1, fp))
    {
        abs->p[abs->num] = tmp;
        abs->num++;
    }

    fclose(fp);
}
//上传结构体内容
void up_file(struct book *abs)
{

    FILE *fp;
    fp = fopen("readme.txt", "w+");

    for (int i = 0; i < abs->num; i++)
        fwrite(&(abs->p[i]), sizeof(struct person), 1, fp); //写入p

    fclose(fp);
}
//以下为实现功能的函数

//添加学生
void add_person(struct book *abs)
{
    char name[10];
    cout << "请输入姓名" << endl;
    cin >> name;
    strcpy(abs->p[abs->num].p_name, name);
    int num1;
    cout << "请输入学号" << endl;
    cin >> num1;
    abs->p[abs->num].p_num1 = num1;
    int num2;
    cout << "请输入房号" << endl;
    cin >> num2;
    abs->p[abs->num].p_num2 = num2;
    abs->num++; //num既充当了数组号，又有统计的功能
}

//修改学生
void change_person(struct book *abs)
{
    int exist1(struct book * abs, string name); //声明
    char name[10];
    cout << "请输入要修改的学生的姓名";
    cin >> name;
    //判断是否存在
    int x = exist1(abs, name); //地址
    if (x != -1)               //开始进行修改
    {
        char name[10];
        cout << "请输入姓名" << endl;
        cin >> name;
        strcpy(abs->p[abs->num].p_name, name);
        int num1;
        cout << "请输入学号" << endl;
        cin >> num1;
        abs->p[abs->num].p_num1 = num1;
        int num2;
        cout << "请输入房号" << endl;
        cin >> num2;
        abs->p[abs->num].p_num2 = num2;
    }
    else
        cout << "查无此人";
}

//删除学生
void delete_person(struct book *abs)
{
    int exist1(struct book * abs, string name); //声明
    string name;
    cout << "请输入要删除学生的名字";
    cin >> name;               //判断是否存在
    int x = exist1(abs, name); //地址
    if (x != -1)               //将后一项值赋给前一项，并只赋值到倒数第一个赋值给倒数第二个，以防出现两个最后一个数
    {
        for (int i = x; i < abs->num; i++)
        {
            abs->p[i] = abs->p[i + 1];
            abs->num--;
        }
    }
    else
        cout << "查无此人" << endl;
}

//菜单功能
void menu()
{
    cout << "******************************" << endl;
    cout << "1、添加学生"
         << "  2、查看学生" << endl;
    cout << "3、查找学生"
         << "  4、删除学生" << endl;
    cout << "5、修改学生"
         << "  6、退出该系统" << endl;
    cout << "******************************" << endl;
}

//查看联系人
void check_book(struct book *abs)
{
    if (abs->num == 0) //检查辅助结构体里的人数，如果为0，提示为空
        cout << "名单为空" << endl;
    else //依次输出通讯录里的人员信息
    {
        for (int i = 0; i < abs->num; i++)
        {
            cout << "姓名" << abs->p[i].p_name << endl;
            cout << "学号" << abs->p[i].p_num1 << endl;
            cout << "房号" << abs->p[i].p_num2 << endl;
            cout << " " << endl;
        }
    }
}

//查找联系人
void cheak_person(struct book *abs, string name, int a, int b) //姓名，学号，房号
{
    if (a == 0 && b == 0)
    {
        int r = exist1(abs, name); //先判断是否存在此人，如不存在，提示为无
        if (r != -1)               //找到人后依次输出
        {
            for (int i = 0; fz1[i] != -1; i++)
            {

                cout << "姓名" << abs->p[fz1[i]].p_name << endl;
                cout << "学号" << abs->p[fz1[i]].p_num1 << endl;
                cout << "房号" << abs->p[fz1[i]].p_num2 << endl;
            }
        }
        else //未找到人
            cout << "未找到联系人" << endl;
    }
    if (a != 0 && b == 0)
    {
        int m = exist2(abs, a); //先判断是否存在此人，如不存在，提示为无
        if (m != -1)            //找到人后依次输出
        {
            cout << "姓名" << abs->p[m].p_name << endl;
            cout << "学号" << abs->p[m].p_num1 << endl;
            cout << "房号" << abs->p[m].p_num2 << endl;
        }
        else //未找到人
            cout << "未找到联系人" << endl;
    }
    if (a == 0 && b != 0)
    {
        int n = exist3(abs, b); //先判断是否存在此人，如不存在，提示为无
        if (n != -1)            //找到人后依次输出
        {
            for (int i = 0; fz[i] != -1; i++)
            {

                cout << "姓名" << abs->p[fz[i]].p_name << endl;
                cout << "学号" << abs->p[fz[i]].p_num1 << endl;
                cout << "房号" << abs->p[fz[i]].p_num2 << endl;
            }
        }
        else //未找到人
            cout << "未找到联系人" << endl;
    }
}

//主函数
int main()
{

    int s;
    struct book abs; //辅助结构体变量
    abs.num = 0;
    loan_file(&abs);
    while (1) //无限循环，确保能一直执行命令
    {

        menu();
        cin >> s;
        switch (s)
        {
        case 1: //1、添加学生(完成)
        {

            add_person(&abs);
            up_file(&abs);
            system("pause");
            system("cls");
        }
        break;
        case 2: //2、查看学生(完成)
        {
            paixv(&abs);
            check_book(&abs);
            system("pause");
            system("cls");
        }
        break;
        case 3: //3、查找学生(完成)
        {
            string name;
            int a, b;
            int i = 0;
            while (i != 4)
            {
                cout << "1 按姓名查询 2按学号查询 3按房号查询 4:退出查询" << endl;
                cin >> i;
                if (i == 1 || i == 2 || i == 3)
                {
                    if (i == 1)
                    {
                        cout << "请输入姓名" << endl;
                        cin >> name;
                        cheak_person(&abs, name, 0, 0);
                    }
                    if (i == 2)
                    {
                        cout << "请输入学号" << endl;
                        cin >> a;
                        cheak_person(&abs, "error", a, 0);
                    }
                    if (i == 3)
                    {
                        cout << "请输入房号" << endl;
                        cin >> b;
                        cheak_person(&abs, "error", 0, b);
                    }
                }
                if (i <= 0 || i > 4)
                {
                    cout << endl;
                    cout << "退出查询请输入 4" << endl;
                    cout << endl;
                }
            }
            system("pause");
            system("cls");
        }
        break;
        case 4: //4、删除学生(完成)
        {
            delete_person(&abs);
            system("pause");
            system("cls");
        }
        break;
        case 5: //5、修改学生(完成)
        {
            change_person(&abs);
            system("pause");
            system("cls");
        }
        break;
        case 6: //6、退出该系统（完成）
        {
            cout << "已保存 ";
            cout << "欢迎您下次使用" << endl;
            up_file(&abs);
            return 0;
        }

        break;
        }
    }
    return 0;
}
